package com.mianle.userapi.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;

/**
 * 金额计算提示使用方式
 */
public class BigNum {

    /**
     * 高精度加法
     *
     * @param v1
     * @param v2
     * @return
     */
    public static BigDecimal add(BigDecimal v1, BigDecimal v2) {
        return v1.add(v2);
    }


    /**
     * 高精度减法
     *
     * @param v1
     * @param v2
     * @return
     */
    public static BigDecimal subtract(BigDecimal v1, BigDecimal v2) {
        return v1.subtract(v2);
    }


    /**
     * 高精度乘法
     *
     * @param v1
     * @param v2
     * @return
     */
    public static BigDecimal multiply(BigDecimal v1, BigDecimal v2) {
        return v1.multiply(v2);
    }


    /**
     * 高精度除法
     *
     * @param v1
     * @param v2
     * @param scale
     * @return
     */
    public static BigDecimal div(BigDecimal v1, BigDecimal v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        return v1.divide(v2, scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 保留小数位
     *
     * @param v
     * @param scale
     * @return
     */
    public static BigDecimal round(BigDecimal v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal one = new BigDecimal("1");
        return v.divide(one, scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 高精度加法
     *
     * @param v1
     * @param items
     * @return
     */
    public static BigDecimal add(BigDecimal v1, BigDecimal... items) {
        if (v1 == null || v1.doubleValue() == 0) {
            v1 = new BigDecimal(0);
        }
        for (BigDecimal item : items) {
            if (item != null && item.doubleValue() > 0) {
                v1 = v1.add(item);
            }
        }
        return round(v1, 2);
    }

    /**
     * 取相反数
     * @param num
     * @return
     */
    public static BigDecimal invert(BigDecimal num){
        return new BigDecimal(0).subtract(num);
    }

    /**
     * 元转换成分
     *
     * @param v
     * @return
     */
    public static Long dollar2penny(BigDecimal v) {
        if (v == null || v.doubleValue() == 0) {
            return 0L;
        }
        BigDecimal s = multiply(v, new BigDecimal(100));
        return s.longValue();
    }

    /**
     * 分转换成元
     *
     * @param v
     * @return
     */
    public static BigDecimal penny2dollar(Long v) {
        if (v == null || v == 0) {
            return new BigDecimal(0);
        }
        return div(new BigDecimal(v), new BigDecimal(100), 2);
    }


    /**
     * 百分比计算
     *
     * @param num   占比值
     * @param total 总值
     * @param scale 精确小数位位数
     * @return
     */
    public static String accuracy(double num, double total, int scale) {
        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
        //可以设置精确几位小数
        df.setMaximumFractionDigits(scale);
        //模式 例如四舍五入
        df.setRoundingMode(RoundingMode.HALF_UP);
        double accuracy_num = num / total * 100;
        return df.format(accuracy_num) + "%";
    }

    /**
     * 百分比Double值
     *
     * @param num   占比值
     * @param total 总值
     * @param scale 精确小数位位数
     * @return
     */
    public static Double accuracyDouble(double num, double total, int scale) {
        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
        //可以设置精确几位小数
        df.setMaximumFractionDigits(scale);
        //模式 例如四舍五入
        df.setRoundingMode(RoundingMode.HALF_UP);
        double accuracy_num = num / total;
        return Double.valueOf(df.format(accuracy_num));
    }

    /**
     * 把double转为字符串输出，最多两位小数
     * @param value
     * @return
     */
    public static String doubleToString(Double value){
        if(value == null)return null;
        value = round(new BigDecimal(value),2).doubleValue();
        if(value%1 == 0){
            return String.valueOf(value.intValue());
        }
        StringBuilder result = new StringBuilder();
        result.append(value.intValue()).append(".");
        int num=  ((int)(value*100))%100;
        result.append(num/10).append(num%10==0?"":num%10);
        return result.toString();
    }


}
